# import re
# from collections import defaultdict
# from typing import Optional, List, NamedTuple
#
# import fitz
#
# # ==============================
# # 请确保以下导入路径正确
# # ==============================
# from tests.base_test import base_test_case
# from tests.pdf_crop_test2 import find_vertical_white_region
#
# logger = base_test_case.get_logger(__name__)
# TEST_DATA_DIR = base_test_case.test_data_dir
# OUTPUT_DATA_DIR = base_test_case.output_data_dir
#
# # ==============================
# # 配置参数
# # ==============================
# DEFAULT_HEADER_HEIGHT = 150
# DEFAULT_FOOTER_HEIGHT = 150
# MAX_HEADER_RATIO = 0.20
# MAX_FOOTER_RATIO = 0.20
# MIN_CONTINUOUS_PAGES = 10
# MAX_EXPANSION_STEPS = 3  # 限制为3轮（符合你“三轮”要求）
# EXPANSION_INCREMENT = 30
#
# input_pdf = TEST_DATA_DIR / "1715339805571.pdf"
#
# # ==============================
# # 数据结构
# # ==============================
# class PageNumberRecord(NamedTuple):
#     num: int
#     page_index: int
#     region: str  # "header", "footer", "left", "right"
#     alignment: str  # "left", "right", "center"
#
#
# def get_alignment(bbox: fitz.Rect, page_width: float) -> str:
#     center_x = (bbox.x0 + bbox.x1) / 2
#     if center_x <= page_width * 0.2:
#         return "left"
#     elif center_x >= page_width * 0.8:
#         return "right"
#     return "center"
#
#
# def is_consecutive_pages(pages: List[int]) -> bool:
#     return all(pages[i] + 1 == pages[i+1] for i in range(len(pages)-1))
#
#
# def is_consecutive_numbers(nums: List[int]) -> bool:
#     return len(nums) >= MIN_CONTINUOUS_PAGES and all(
#         nums[i] + 1 == nums[i + 1] for i in range(len(nums) - 1)
#     )
#
#
# def detect_page_number_in_region(doc: fitz.Document, expansion_step: int = 0) -> Optional[fitz.Rect]:
#     total_pages = len(doc)
#     if total_pages < MIN_CONTINUOUS_PAGES:
#         return None
#
#     sample_n = min(total_pages, max(15, MIN_CONTINUOUS_PAGES))
#     all_records: List[PageNumberRecord] = []
#
#     for idx in range(sample_n):
#         page = doc[idx]
#         roi = find_vertical_white_region(page, zoom_factor=1.0)
#         if not roi:
#             continue
#
#         x0, y0, x1, y1 = roi
#         w = page.rect.width
#         h = page.rect.height
#
#         expansion = expansion_step * EXPANSION_INCREMENT
#         header_bottom = min(y0 + expansion, h * MAX_HEADER_RATIO)
#         footer_top = max(y1 - expansion, h * (1 - MAX_FOOTER_RATIO))
#
#         # 四个区域（严格按你设计）
#         regions = {
#             "header": (fitz.Rect(0, 0, w, header_bottom), lambda bbox: get_alignment(bbox, w)),
#             "footer": (fitz.Rect(0, footer_top, w, h), lambda bbox: get_alignment(bbox, w)),
#             "left":   (fitz.Rect(0, y0, max(0, x0 - expansion), y1), lambda _: "left"),
#             "right":  (fitz.Rect(min(w, x1 + expansion), y0, w, y1), lambda _: "right"),
#         }
#
#         for region_name, (clip_rect, align_fn) in regions.items():
#             # ✅ 关键修复：不用 get_area()，改用 width/height 判断
#             if clip_rect.width <= 0 or clip_rect.height <= 0:
#                 continue
#
#             text_dict = page.get_text("dict", clip=clip_rect)
#             for block in text_dict.get("blocks", []):
#                 for line in block.get("lines", []):
#                     for span in line.get("spans", []):
#                         text = span["text"]
#                         bbox = fitz.Rect(span["bbox"])
#                         for match in re.finditer(r'\b(\d+)\b', text):
#                             try:
#                                 num = int(match.group(1))
#                                 if num <= 0:
#                                     continue
#                             except ValueError:
#                                 continue
#
#                             align = align_fn(bbox)
#                             if align in ("left", "right", "center"):
#                                 all_records.append(PageNumberRecord(num, idx, region_name, align))
#
#     if not all_records:
#         return None
#
#     clusters = defaultdict(list)
#     for rec in all_records:
#         clusters[(rec.region, rec.alignment)].append(rec)
#
#     for (region, align), group in clusters.items():
#         if len(group) < MIN_CONTINUOUS_PAGES:
#             continue
#         group.sort(key=lambda x: x.page_index)
#         pages = [r.page_index for r in group]
#         nums = [r.num for r in group]
#
#         if is_consecutive_pages(pages) and is_consecutive_numbers(nums):
#             # 返回第一页的对应区域
#             first_page = doc[0]
#             roi0 = find_vertical_white_region(first_page, zoom_factor=1.0)
#             if not roi0:
#                 continue
#             x0_0, y0_0, x1_0, y1_0 = roi0
#             w0, h0 = first_page.rect.width, first_page.rect.height
#             expansion = expansion_step * EXPANSION_INCREMENT
#
#             if region == "header":
#                 header_bottom = min(y0_0 + expansion, h0 * MAX_HEADER_RATIO)
#                 return fitz.Rect(0, 0, w0, header_bottom)
#             elif region == "footer":
#                 footer_top = max(y1_0 - expansion, h0 * (1 - MAX_FOOTER_RATIO))
#                 return fitz.Rect(0, footer_top, w0, h0)
#             elif region == "left":
#                 return fitz.Rect(0, y0_0, max(0, x0_0 - expansion), y1_0)
#             elif region == "right":
#                 return fitz.Rect(min(w0, x1_0 + expansion), y0_0, w0, y1_0)
#
#     return None
#
#
# def detect_page_number_region(doc: fitz.Document) -> Optional[fitz.Rect]:
#     # 第一轮：不扩展
#     rect = detect_page_number_in_region(doc, expansion_step=0)
#     if rect:
#         print("✅ 第一轮检测成功")
#         return rect
#
#     # 第二轮：扩展1次
#     print("⚠️ 第一轮失败，尝试第二轮（扩展1次）")
#     rect = detect_page_number_in_region(doc, expansion_step=1)
#     if rect:
#         print("✅ 第二轮检测成功")
#         return rect
#
#     # 第三轮：扩展2次
#     print("⚠️ 第二轮失败，尝试第三轮（扩展2次）")
#     rect = detect_page_number_in_region(doc, expansion_step=2)
#     if rect:
#         print("✅ 第三轮检测成功")
#         return rect
#
#     print("❌ 三轮均失败，无页码区域")
#     return None
#
#
# def main():
#     if not input_pdf.exists():
#         raise FileNotFoundError(f"PDF not found: {input_pdf}")
#
#     doc = fitz.open(input_pdf)
#     try:
#         rect = detect_page_number_region(doc)
#         if rect:
#             print(f"✅ 最终页码区域: {rect}")
#         else:
#             print("❌ 未检测到页码")
#     finally:
#         doc.close()
#
#
# if __name__ == "__main__":
#     # 多轮检查测试示例 TODO 功能待完善
#     # ⚠️ 第一轮失败，尝试第二轮（扩展1次）
#     # ⚠️ 第二轮失败，尝试第三轮（扩展2次）
#     # ❌ 三轮均失败，无页码区域
#     main()